
package com.studiofortress.sf.util.structure.loading;

import com.studiofortress.sf.graphics.GraphicsGL;
import com.studiofortress.sf.structure.Actor;
import com.studiofortress.sf.structure.World;
import java.util.List;
import java.util.ArrayList;

/**
 * This is a simple World for creating loading screens. Loading jobs are added
 * and can then be called in turn from the 'loadAction' method.
 * 
 * @author Joseph Lenton
 * @param A The type of Actor this LoadingWorld will contain.
 */
public class LoadingWorld<G extends GraphicsGL, A extends Actor<? super G>> extends World<G, A>
{
    private List<LoadAction> loadingActions;
    
    /**
     * @param width The width of this world, must be greater then 0.
     * @param height The height of this world, must be greater then 0.
     */
    public LoadingWorld(int width, int height)
    {
        super( width, height );
    }

    /**
     * @param width The width of this world, must be greater then 0.
     * @param height The height of this world, must be greater then 0.
     * @param x The x location of this world.
     * @param y The y location of this world.
     */
    public LoadingWorld(int width, int height, int x, int y)
    {
        super( width, height, x, y );
    }

    /**
     * Creates where we will be storing the loadingActions for all constructors.
     */
    {
        loadingActions = new ArrayList<LoadAction>();
    }

    /**
     * Adds all the given actions as loading jobs to be performed. They can be
     * run and removed by calling the 'loadAction' method.
     * None of the given actions can be null.
     * @param actions The actions to load, cannot be null.
     */
    public void add(LoadAction ... actions)
    {
        if (actions == null) {
            throw new IllegalArgumentException("The given actions cannot be null.");
        }

        for (int i = actions.length-1; i >= 0; i--) {
            LoadAction action = actions[i];
            if (action == null) {
                throw new IllegalArgumentException("None of the given actions can be null. Null found at action: " + i);
            }

            loadingActions.add( action );
        }
    }
    
    /**
     * Removes the next action to be loaded and executes it.
     * @return True if the action run is the last actions, otherwise false.
     */
    protected boolean loadAction()
    {
        loadingActions.remove( loadingActions.size()-1 ).action();
        return isEmpty();
    }
    
    /**
     * @return The number of actions left to be run.
     */
    public int size()
    {
        return loadingActions.size();
    }
    
    /**
     * @return True if there are no more actions to be run, otherwise false.
     */
    public boolean isEmpty()
    {
        return size() == 0;
    }
}
